package com.example.springboot.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.example.springboot.common.ResultCode;
import com.example.springboot.common.config.JwtTokenUtils;
import com.example.springboot.dao.AdminMapper;
import com.example.springboot.dao.GradeMapper;
import com.example.springboot.dao.UserMapper;
import com.example.springboot.domain.po.*;
import com.example.springboot.domain.po.User;
import com.example.springboot.exception.CustomException;
import com.example.springboot.service.AdminService;
import com.example.springboot.service.UserService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.beans.Transient;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author：伐柯梦姝
 * @Package：com.example.springboot.service.Impl
 * @Project：springboot
 * @name：UserServiceImpl
 * @Date：2025/2/4 21:13
 * @Filename：UserServiceImpl
 * @for:
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private UserMapper userMapper;
    @Resource
    private GradeMapper gradeMapper;
    @Resource
    private AdminMapper adminMapper;

    @Override
    public List<User> getAll() {
        List<User> list = lambdaQuery().list();
        return list;
    }

    @Override
    public User userRegister(User user) {
        //1、拿到用户输入的用户名，取数据库查询是否存在，如果存在抛出异常
        User user1 = this.selectByUserName(user.getUsername());
        if (ObjectUtil.isNotEmpty(user1)) {//如果找到这个用户，抛出异常提示用户已存在
            throw new CustomException(ResultCode.USER_EXIST_ERROR);
        }
        //设置默认头像
        if (ObjectUtil.isEmpty(user.getAvatar())) {
            user.setAvatar("http://localhost:8081/files/1738921400311-微信图片_20240701092647.png");
        }
        //设置默认密码
        if (ObjectUtil.isEmpty(user.getPassword())) {
            user.setPassword("asd");
        }
        user.setRole(2);
        //2、把用户注册信息写到数据库表中
        this.save(user);
        return user;
    }

    @Override
    public User userLogin(User user) {
        User user1 = this.selectByNameAndPassword(user.getUsername(), user.getPassword());
        if (ObjectUtil.isNotEmpty(user1)) {
            return user1;
        } else {
            throw new CustomException(ResultCode.USER_ACCOUNT_ERROR);
        }
    }

    @Override
    public User findById(Integer id) {
        return this.getById(id);
    }

    @Override
    public PageInfo<User> findPage(User search, Integer pageNum, Integer pageSize) {
        Account user = JwtTokenUtils.getCurrentUser();
        if (ObjectUtil.isEmpty(user)) {
            throw new CustomException(ResultCode.USER_NOT_LOGIN);
        }
        if (ObjectUtil.isNotEmpty(search) && ObjectUtil.isNotEmpty(search.getGradeName())) {
            Grade grade = gradeMapper.selectByGradeName(search.getGradeName());
            search.setGradeId(grade.getId());
        }
        // 开启分页 一定要在操作数据库方法的上面
        PageHelper.startPage(pageNum, pageSize);
        List<User> all = this.findByCondition(search);
        all.forEach(user1 -> {
            String gradeName = gradeMapper.selectGradeNameById(user1.getGradeId());
            user1.setGradeName(gradeName);
        });

        return PageInfo.of(all);
    }

    @Transactional
    @Override
    public User userRole(User user) {

//        1.执行删除操作:在管理员表里删除这个用户
        Integer id = user.getId(); //拿到用户的Id
        this.deleteById(id);
        Admin admin = BeanUtil.copyProperties(user, Admin.class);
        admin.setRole(1);
        admin.setId(null);
        //2、校验是否有重复用户名
        QueryWrapper<Admin> wrapper = new QueryWrapper<Admin>()
                .eq("username", admin.getUsername());
        Admin admin1 = adminMapper.selectOne(wrapper);
        if (ObjectUtil.isNotEmpty(admin1)){
            throw  new CustomException(ResultCode.USER_EXIST_ERROR);
        }
//        3.把这个管理的信息新增到用户表
        adminMapper.insert(admin);
        return user;
    }

    @Override
    public void exportById(Integer id, HttpServletResponse response) throws IOException {
        User user = this.findById(id);

        List<Map<String, Object>> list = new ArrayList<>();
        if (ObjectUtil.isEmpty(user)) {
            throw new CustomException("-1", "未查询到数据");
        }
        Map<String, Object> row = new LinkedHashMap<>(1);
        row.put("用户名", user.getUsername());
        row.put("性别", user.getGender());
        row.put("年龄", user.getAge());
        row.put("电话", user.getPhone());
        row.put("角色标识", user.getRole());
        row.put("班级Id", user.getGradeId());
        row.put("档案信息", user.getArchival());
        list.add(row);
        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.write(list, true);//把k-v的 k作为表头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename="+ user.getUsername() +"Archival.xlsx");
        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(System.out);
    }

    @Override
    public void deleteBatch(List<User> list) {
        //        后端拿到前端传过来的集合，执行循环删除操作
        for (User user : list) {
//            调用Service层已经写好的删除方法
            this.deleteById(user.getId());
        }
    }

    @Override
    public User selectById(Integer id) {
        return userMapper.selectById(id);
    }



    @Override
    public void deleteById(Integer id) {
        this.removeById(id);
    }

    @Override
    public void update(User user) {
        //如果用户名为空，抛出异常
        String username = user.getUsername();
        if (!ObjectUtil.isNotEmpty(username)){
            throw new CustomException(ResultCode.USERNAME_ISNULL_ERROR);
        }
        //插入前做用户名唯一性校验
        User user1 = this.selectByUserName(username);
        //如果修改的用户名与当前正在用的用户名一致，不需要再做唯一性校验
        User user2 = this.getById(user.getId());
        if (user2.getUsername().equals(username)){
            this.saveOrUpdate(user);
        }else if (ObjectUtil.isNotEmpty(user1)){
            throw  new CustomException(ResultCode.USER_EXIST_ERROR);
        }
        this.saveOrUpdate(user);
    }

    @Override
    public List<User> findByCondition(User user){
        QueryWrapper<User> wrapper = new QueryWrapper<User>()
                .like(user != null && ObjectUtil.isNotEmpty(user.getUsername()) && !user.getUsername().contains("undefined"),"username", user.getUsername())
                .eq(user != null && ObjectUtil.isNotEmpty(user.getGradeId()),"grade_id", user.getGradeId());
        return userMapper.selectList(wrapper);

    }

    @Override
    public void export(String gradeName, String username, HttpServletResponse response) throws IOException {
        User search = new User();
        search.setUsername(username);
        search.setGradeName(gradeName);
        if (ObjectUtil.isNotEmpty(search) && ObjectUtil.isNotEmpty(search.getGradeName()) && !search.getGradeName().contains("undefined")) {
            Grade grade = gradeMapper.selectByGradeName(search.getGradeName());
            search.setGradeId(grade.getId());
        }
        List<User> all = this.findByCondition(search);
        if (CollectionUtil.isEmpty(all)) {
            throw new CustomException("-1", "未查询到数据");
        }
        List<Map<String, Object>> list = new ArrayList<>(all.size());
        if (CollectionUtil.isEmpty(all)) {
            throw new CustomException("-1", "未查询到数据");
        }
        for (User user : all) {
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("用户名", user.getUsername());
            row.put("性别", user.getGender());
            row.put("年龄", user.getAge());
            row.put("电话", user.getPhone());
            row.put("角色标识", user.getRole());
            row.put("班级Id", user.getGradeId());
            row.put("档案信息", user.getArchival());
            list.add(row);
        }


        ExcelWriter writer = ExcelUtil.getWriter(true);
        writer.write(list, true);//把k-v的 k作为表头
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=userInfoExcel.xlsx");
        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        writer.close();
        IoUtil.close(System.out);
    }


    public User selectByUserName(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
                .eq("username", username);
        return userMapper.selectOne(queryWrapper);
    }

    public User selectByNameAndPassword(String username, String password) {
        QueryWrapper<User> wrapper = new QueryWrapper<User>()
                .eq("username", username)
                .eq("password", password);
        return userMapper.selectOne(wrapper);
    }
}
